/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pbl_cliente;

import java.net.Socket;
import java.util.List;
import InterfaceCliente.*;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

/**
 * @author Tayane
 */
public class CotaChat extends Observable {
    
    private int id_cota;
    private String ipMulticast;
    private int portaMulticast;
    private int qntRecusas = 0;
    private List<Socket> listaSocketConfirmados;
    private List<Socket> listaSocketConvidados;
    private Boolean tenhoCota = false;
    private Boolean salaAtiva = false;
    private JanelaChat janelaChat;
    private String meuEmail;
    private String mensagem;
    private PBL_cliente cli;
    private Boolean donoDaCota;
    private RecebeMsgMulticast recebeMsgMulticast;
            
    public CotaChat(PBL_cliente cli){
        this.listaSocketConfirmados = new ArrayList<Socket>();
        this.listaSocketConvidados = new ArrayList<Socket>();
        this.cli = cli;
        this.setMeuEmail(cli.getEmailUsuarioConectado());
    }

    public Boolean getTenhoCota() {
        return tenhoCota;
    }

    public void setMeuEmail(String meuEmail) {
        this.meuEmail = meuEmail;
    }

    public Boolean getDonoDaCota() {
        return donoDaCota;
    }

    public void setDonoDaCota(Boolean donoDaCota) {
        this.donoDaCota = donoDaCota;
    }
    
    public void setTenhoCota(Boolean tenhoCota) {
        this.tenhoCota = tenhoCota;
    }

    public int getPortaMulticast() {
        return portaMulticast;
    }

    public void setPortaMulticast(int portaMulticast) {
        this.portaMulticast = portaMulticast;
    }
    
    public List<Socket> getListaSocketConfirmados() {
        return listaSocketConfirmados;
    }

    public List<Socket> getListaSocketConvidados() {
        return listaSocketConvidados;
    }

    public void incRecusas(){
        this.qntRecusas++;
        if(qntRecusas == listaSocketConvidados.size()){
            //TEM QUE ENVIAR MENSAGEM PARA O SERVIDOR DIZENDO QUE ESTÁ DEVOLVENDO A COTA E ENCERRAR ESSE OBJETO!
            cli.incContChat();
            System.out.println("Cota liberada para o servidor pois todos os convidados recusaram");
        }
    }
    
    public void addConvidado(Socket convidado){
        listaSocketConvidados.add(convidado);
    }
    
    public void addConfirmado(Socket participante){
        if((this.getTenhoCota() == true) && (this.getSalaAtiva() == false)){
            listaSocketConfirmados.add(participante);
            try {
                DataOutputStream msg = new DataOutputStream(participante.getOutputStream());
                msg.writeUTF("AtivarSala:" + this.getId_cota() + ":"  + this.getIpMulticast() + ":" + this.getPortaMulticast());
                System.out.println("AtivarSala:" + this.getId_cota() + ":"  + this.getIpMulticast() + ":" + this.getPortaMulticast());
                this.setSalaAtiva(true);
            } catch (IOException ex) {
                Logger.getLogger(CotaChat.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        else if((this.getTenhoCota() == true) && (this.getSalaAtiva() == true)){
            listaSocketConfirmados.add(participante);
            try {
                DataOutputStream msg = new DataOutputStream(participante.getOutputStream());
                msg.writeUTF("AtivarSala:" + this.getId_cota() + ":"  + this.getIpMulticast() + ":" + this.getPortaMulticast());
                System.out.println("AtivarSala:" + this.getId_cota() + ":"  + this.getIpMulticast() + ":" + this.getPortaMulticast());
            } catch (IOException ex) {
                Logger.getLogger(CotaChat.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        else{
            listaSocketConfirmados.add(participante);
        }
    }

    public int getId_cota() {
        return id_cota;
    }

    public void setId_cota(int id_cota) {
        this.id_cota = id_cota;
    }

    public Boolean getSalaAtiva() {
        return salaAtiva;
    }

    public void setSalaAtiva(Boolean salaAtiva) {
        this.salaAtiva = true;
        this.janelaChat = new JanelaChat(this, cli);
        recebeMsgMulticast = new RecebeMsgMulticast(ipMulticast, portaMulticast, this);
        new Thread(recebeMsgMulticast).start();
        this.notifica("Chat iniciado às " + getHora() + "\n");
    }
    
    public void fechaJanela(){
        JOptionPane.showMessageDialog(null, "Esta janela será fechada pois o solicitador dela não está mais ativo");
        this.janelaChat.dispose();
        cli.incContChat();
    }

    public String getIpMulticast() {
        return ipMulticast;
    }

    public void setIpMulticast(String ipMulticast) {
        this.ipMulticast = ipMulticast;
    }
    
//    public void envia(String texto) { //ALTERAR ESSE MÉTODO PARA USAR MULTICAST!
//        for (int i = 0; i < listaSocketConfirmados.size(); i++){
//            try {
//                DataOutputStream msg = new DataOutputStream(listaSocketConfirmados.get(i).getOutputStream());
//                msg.writeUTF(this.meuEmail + " diz: " + texto);
//                System.out.println("Enviei msg pelo chat: " + " para " + listaSocketConfirmados.get(i).getInetAddress());
//            } catch (IOException ex) {
//                Logger.getLogger(CotaChat.class.getName()).log(Level.SEVERE, null, ex);
//                System.out.println("Não foi possível enviar msg do chat para os participantes");
//            }
//        }
//    }
    
    public void recebiCota(){
        if(listaSocketConfirmados.size() > 0){
            for(int i = 0; i < listaSocketConfirmados.size(); i++){
                try {
                    DataOutputStream msg = new DataOutputStream(listaSocketConfirmados.get(i).getOutputStream());
                    msg.writeUTF("RecebiCota:" + this.getId_cota() + ":" + this.getIpMulticast());
                } catch (IOException ex) {
                    Logger.getLogger(CotaChat.class.getName()).log(Level.SEVERE, null, ex);
                    System.out.println("Não foi possível enviar msg de aviso de confirmação de cota para os convidados confirmados");
                }
            }
        }
        else {
            this.setTenhoCota(true);
        }
    }
    
    public void naoRecebiCota(){
       for(int i = 0; i < listaSocketConfirmados.size(); i++){
            try {
                DataOutputStream msg = new DataOutputStream(listaSocketConfirmados.get(i).getOutputStream());
                msg.writeUTF("NaoRecebiCota");
            } catch (IOException ex) {
                Logger.getLogger(CotaChat.class.getName()).log(Level.SEVERE, null, ex);
                System.out.println("Não foi possível enviar msg avisando que não tenho a cota ao convidados convidados");
            }
      }
    }
    
    public void enviaAvisoFecheiJanela(){
        for(int i = 0; i < listaSocketConfirmados.size(); i++){
            try {
                DataOutputStream msg = new DataOutputStream(listaSocketConfirmados.get(i).getOutputStream());
                msg.writeUTF("FecheiJanela:" + this.getId_cota() + ":" + this.getIpMulticast());
            } catch (IOException ex) {
                Logger.getLogger(CotaChat.class.getName()).log(Level.SEVERE, null, ex);
                System.out.println("Não foi possível enviar msg de aviso de fechamento de janela para os convidados confirmados");
            }
        }        
    }
    
    public String getMensagem() {
        return mensagem;
    }
    
    public void notifica(String mensagem) {
        this.mensagem = mensagem;
        setChanged();
        notifyObservers();
    } 
    
   private String getHora() {
       DateFormat dateFormat = new SimpleDateFormat("HH:mm");
       Date date = new Date();
       return dateFormat.format(date);
   }
   
   public void enviaMsgMulticast(String msgChat) throws SocketException, UnknownHostException, IOException{
       
       DatagramSocket s = new DatagramSocket();     
       String msg =  this.meuEmail + " diz: " + msgChat + "§";
       byte buf[] = msg.getBytes();   
       DatagramPacket pack = new DatagramPacket(buf,buf.length,InetAddress.getByName(this.getIpMulticast()), this.getPortaMulticast());
       s.send(pack);
       System.out.println("Mensagem enviada multicast: " + pack.getData().toString());
   }
    
}
